#include<iostream>
#include<thread>
#include<string>
#include<vector>
#include<list>
#include<mutex>

using namespace std;

//准备用成员函数作为线程函数的方法写线程，成为消息处理类
class A{
public:
	//把收到的消息入到一个队列的线程
	void inMsgRecvQueue(){
		for (int i = 0; i < 10000; i++){
			cout << "inMsgRecvQueue()执行，插入一个元素" << i << endl;
			{
				lock_guard<mutex> lGuard(my_mutex);
				//my_mutex.lock();
				msgRecvQueue.push_back(i); //存放消息
				//my_mutex.unlock();
			}

		}
	}

	//将共享的代码放到一个函数处理,方便上锁解锁
	bool outMsgLULProc(int &command){
		lock_guard<mutex> lGuard(my_mutex);
		//my_mutex.lock();
		if (!msgRecvQueue.empty()){
			int command = msgRecvQueue.front();
			msgRecvQueue.pop_front();
			//my_mutex.unlock();  //所有分支都必须有unlock()
			return true;
		}
		//my_mutex.unlock();
		return false;
	}

	//把数据从消息队列取出的线程
	void outMsgRecvQueue(){
		int command = 0;
		for (int i = 0; i < 10000; i++){
			bool result = outMsgLULProc(command);
			if (result == true){
				cout << "outMsgRecvQueue()执行，取出一个元素" << endl;
				//处理数据
				//这里有可能也有需要共享的代码段
			}
			if (result == false){
				//消息队列为空
				cout << "inMsgRecvQueue()执行，但目前消息队列中为空！" << i << endl;
			}
		}
		cout << "end!" << endl;
	}

private:
	std::list<int> msgRecvQueue;//容器（消息队列），代表玩家发送过来的命令。
	std::mutex my_mutex;
};

int main(){
	A myobja;

	thread myOutMsgObj(&A::outMsgRecvQueue, &myobja);//第二个参数，地址，才能保证线程里用的是同一个对象
	thread myInMsgObj(&A::inMsgRecvQueue, &myobja);

	myOutMsgObj.join();
	myInMsgObj.join();

	cout << "主线程执行！" << endl;

	return 0;
}
